<script setup name="JXGXTopic">
import { ref, onMounted, onBeforeUnmount, watch, computed, nextTick } from 'vue'
import { getAllMachine } from '@/api/pannel/machinePannel.js'
import MqttServer from '@/socket/mqtt'
import { prdPrdLineApi } from '@/api/globalApi'
import { getgxdlxxNow } from '@/api/processClassNow.js'
import moment from 'moment'
const machineList = ref([])
const topics = ref([])
const options = ref([])
const lineList = ref([])
const ChartData = ref([])
const machineStatus = ref([])
const lastUpdateTime = ref(0)
const params = ref({
  lineID: '',
  prodLine: ''
})
let mqttServer = null

const getCurrentShift = () => {
  const now = moment() // 当前时间
  const startOfDay = moment().startOf('day') // 当天的开始时间

  // 定义白班和晚班的时间区间
  const dayShiftStart = startOfDay.clone().add(8, 'hours').add(30, 'minutes') // 8:30
  const dayShiftEnd = startOfDay.clone().add(20, 'hours').add(30, 'minutes') // 20:30

  // 判断是否在白班时间区间内
  if (now.isBetween(dayShiftStart, dayShiftEnd)) {
    return '1'
  }

  // 否则为晚班
  return '2'
}

const ChartOption = computed(() => ({
  title: {
    text: '产品产出统计',
    textStyle: {
      color: '#fff',
      fontSize: 16,
      fontWeight: 'bold'
    },
    left: 'center'
  },
  tooltip: {
    trigger: 'item'
  },
  grid: {
    left: '20%',
    right: '20%',
    bottom: '3%',
    containLabel: true
  },

  series: [
    {
      name: '产品',
      type: 'pie',
      data: ChartData.value,

      radius: '40%',
      label: {
        color: '#fff',
        formatter: '{b}:{d}%'
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
}))

// 翻页相关变量
const currentPage = ref(0)
const itemsPerRow = ref(0) // 每行显示的项目数量，自动计算
const itemsPerPage = computed(() => itemsPerRow.value * 3) // 每页两行
const totalPages = ref(0)
let pageInterval = null
const scrollY = ref(0) // 滚动的Y轴距离
const isHovered = ref(false) // 标记是否鼠标悬停
const machineOutputValue = ref([])
const changeName = ref([])

// 计算每行显示的项目数量
const calculateItemsPerRow = () => {
  const container = document.querySelector('.ps-machine-viewport')
  if (container) {
    // 获取容器宽度和每个项目宽度
    const containerWidth = container.offsetWidth
    const itemWidth = 150 // 与CSS中设置的宽度一致

    // 计算每行可容纳的项目数（考虑间距）
    itemsPerRow.value = Math.floor(containerWidth / (itemWidth + 10)) // 10是grid-gap
    // 至少显示1个项目
    itemsPerRow.value = Math.max(1, itemsPerRow.value)
    console.log('itemsPerRow', itemsPerRow.value, containerWidth)
  }
}

// 初始化分页
const initPagination = () => {
  // 等待DOM更新后计算每行可显示的项目数
  setTimeout(() => {
    calculateItemsPerRow()
    currentPage.value = 0
    scrollY.value = 0 // 重置滚动位置
    totalPages.value = Math.max(1, Math.ceil(machineList.value.length / itemsPerPage.value))
  }, 0)
}

// 切换到指定页
const goToPage = page => {
  if (page < 0) page = 0
  if (page >= totalPages.value) page = totalPages.value - 1

  // 计算新的滚动位置（每页高度为两行的高度）
  const itemHeight = 100 + 22 // 每个项目的高度
  const rowGap = 20 // 行间距
  scrollY.value = page * (itemHeight * 2 + rowGap)
  currentPage.value = page
}

// 上一页
const prevPage = () => {
  goToPage(currentPage.value - 1)
}

// 下一页
const nextPage = () => {
  goToPage(currentPage.value + 1)
}

// 自动翻页
const startAutoPage = () => {
  // 清除可能存在的旧定时器
  if (pageInterval) {
    clearInterval(pageInterval)
  }

  // 每3秒翻一页
  pageInterval = setInterval(() => {
    // 鼠标悬停或只有一页时不翻页
    if (totalPages.value <= 1 || isHovered.value) return

    const nextPage = (currentPage.value + 1) % totalPages.value
    goToPage(nextPage)
  }, 3000 * 10) // 3秒 = 3000毫秒
}

// 暂停自动翻页
const pauseAutoPage = () => {
  isHovered.value = true
}

// 恢复自动翻页
const resumeAutoPage = () => {
  isHovered.value = false
}

const loadLineList = async () => {
  const { data } = await prdPrdLineApi()
  lineList.value = data
}

/**
 * @description: 加载工序大类选项
 */
const loadProcessOptions = async () => {
  const { data } = await getgxdlxxNow()
  options.value = data
}

const loadData = async () => {
  // 清除现有定时器
  if (pageInterval) {
    clearInterval(pageInterval)
  }

  // 清空现有数据
  machineList.value = []
  topics.value = []

  const { machines } = await getAllMachine({ ...params.value, key: 'topic' })

  for (let index = 0; index < machines.length; index++) {
    const item = machines[index]

    item.type = item.zt === '未开工' ? 'red' : item.gxmc.includes('调机') ? 'blur' : 'green'
    if (item.topic) {
      item.sj = 0
      item.oldValue = 0
      item.showTipicIcon = false
      item.runTime = 0
      topics.value.push(item.topic)
      item.ToQuantity = 0
      item.Alarm = '无报警'
      item.FromQuantity = 0
      item.Running = '停止'
      item.RunningValue = 0
      item.AlarmValue = 0
    }
    machineList.value.push({ ...item })
  }

  // 初始化翻页
  initPagination()
  initMqttServer()

  // 等待DOM更新后启动自动翻页
  nextTick(() => {
    startAutoPage()
  })
}

const handleMessage = message => {
  const { topic } = message

  const data = JSON.parse(message.payloadString)
  const index = machineList.value.findIndex(item => item.topic === topic)
  if (index > -1) {
    const { Quantity = 0 } = machineList.value[index]

    const { Time, Name, Daytime, Nighttime, Alarm, Running } = data
    const CurrentShift = getCurrentShift()
    machineList.value[index] = {
      ...machineList.value[index],
      Time,
      Name,
      FromQuantity: Quantity,
      ToQuantity: CurrentShift == 1 ? Number(Daytime) : Number(Nighttime),
      Alarm: Alarm == 0 ? '无报警' : '报警中',
      Running: Running == 0 ? '停止' : '运行中',
      RunningValue: Running == 0 ? 0 : 1,
      AlarmValue: Alarm == 0 ? 0 : 1
    }
    const jndex = changeName.value.indexOf(Name)

    if (jndex == -1) {
      changeName.value.push(Name)
      const dndex = changeName.value.indexOf(Name)
      setTimeout(() => {
        changeName.value.splice(dndex, 1)
      }, 1000)
    } else {
      setTimeout(() => {
        changeName.value.splice(jndex, 1)
      }, 1000)
    }
    statisticsMachineInfo()
  }
}

const initMqttServer = () => {
  if (mqttServer === null) {
    mqttServer = new MqttServer([topics.value])
    mqttServer.addMessageCallback(handleMessage)
  }
}

// 监听窗口大小变化，重新计算每行项目数
const handleResize = () => {
  const oldItemsPerRow = itemsPerRow.value
  calculateItemsPerRow()

  // 如果每行项目数变化，重新计算分页
  if (oldItemsPerRow !== itemsPerRow.value) {
    const currentPageNum = currentPage.value
    initPagination()
    // 保持在当前页
    nextTick(() => {
      goToPage(currentPageNum)
    })
  }
}

// 统计设备信息
const statisticsMachineInfo = () => {
  const ClassTotal = []
  // 计算设备当前累计生产

  const StatusTotal = [
    { name: '运行中', total: 0, color: '#28a745' },
    { name: '停止', total: 0, color: 'gray' },
    { name: '无警报', total: 0, color: '#fff' },
    { name: '警报中', total: 0, color: 'red' }
  ]
  machineList.value.forEach(machine => {
    const findIndex = ClassTotal.findIndex(item => item.name === machine.Name)
    // RunningValue AlarmValue
    if (machine.RunningValue == 0) {
      StatusTotal[1].total += 1
    } else {
      StatusTotal[0].total += 1
    }

    if (machine.AlarmValue == 0) {
      StatusTotal[2].total += 1
    } else {
      StatusTotal[3].total += 1
    }

    if (findIndex === -1) {
      if (machine.Name) {
        ClassTotal.push({
          name: machine.Name,
          value: Number(machine.ToQuantity),
          displayTotal: Number(machine.ToQuantity),
          change: 'up',
          showIndicator: true
        })
      }
    } else {
      ClassTotal[findIndex].value += Number(machine.ToQuantity)
    }
  })
  const now = Date.now()
  if (
    now - lastUpdateTime.value > 1000 * 60 * 5 ||
    lastUpdateTime.value === 0 ||
    ChartData.value.length !== ClassTotal.length
  ) {
    ChartData.value = ClassTotal
    lastUpdateTime.value = now
  }
  machineStatus.value = StatusTotal

  machineOutputValue.value = ClassTotal.sort((a, b) => b.total - a.total)
}

// 监听设备列表变化，更新分页
watch(machineList, () => {
  initPagination()
})

onMounted(() => {
  loadData()
  loadLineList()
  loadProcessOptions()
  window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
  // 清除定时器
  if (pageInterval) {
    clearInterval(pageInterval)
  }
  // 断开mqtt连接
  if (mqttServer) {
    mqttServer.disconnect() // 假设存在disconnect方法
  }
  window.removeEventListener('resize', handleResize)
})
</script>

<template>
  <div class="ps_board" style="display: grid; grid-template-rows: auto 280px 1fr auto">
    <ps-header :showDecoration5="false">
      <template #header>
        <select class="chart-select" v-model="params.lineID" @change="loadData">
          <option :value="''">全部</option>
          <option v-for="item in options" :key="item.Udef1" :value="item.Udef1">
            {{ item.Udef1 }}
          </option>
        </select>

        <select class="chart-select" v-model="params.prodLine" @change="loadData">
          <option :value="''">全部</option>
          <option v-for="item in lineList" :key="item.value" :value="item.value">
            {{ item.LineName }}
          </option>
        </select>
      </template>
    </ps-header>

    <div class="ps-machine-viewport" @mouseenter="pauseAutoPage" @mouseleave="resumeAutoPage">
      <div
        class="ps-machine"
        :style="{
          transform: `translateY(-${scrollY}px)`,
          transition: 'transform 0.5s ease-out'
        }"
      >
        <div
          class="ps-machine-item"
          v-for="machine in machineList"
          :key="machine.jtbh"
          :style="{
            'border-color': machine.RunningValue == 0 ? 'gray' : 'var(--cbs-machine-green)'
          }"
        >
          <div
            class="machineID"
            :style="{
              'background-color': machine.RunningValue == 0 ? 'gray' : 'var(--cbs-machine-green)'
            }"
          >
            <span>{{ machine.Running }}</span>
          </div>

          <div class="machineName">
            <span>{{ machine.jtmc }}</span>
            <template v-if="machine.topic && machine.showTipicIcon">
              <el-icon name="Sort" size="16" style="color: var(--cbs-machine-green)"><Sort /></el-icon>
            </template>
          </div>

          <div class="desc-item" v-if="machine.topic">
            <span class="label">产品名称：</span>
            <span>{{ machine.Name }}</span>
          </div>

          <div class="desc-item" v-if="machine.topic">
            <span class="label">生产数量：</span>

            <template v-if="machine.ToQuantity">
              <AnimatedNumber
                style="display: inline-block"
                :from="machine.FromQuantity"
                :to="machine.ToQuantity"
                :key="machine.ToQuantity"
                :duration="1000"
              />
            </template>
          </div>

          <div class="desc-item" v-if="machine.topic">
            <span class="label">更新时间：</span>
            <span>{{ machine.Time }}</span>
          </div>
        </div>
      </div>
    </div>

    <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; color: #fff; padding: 10px; height: 100%">
      <div class="statistic-list" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px">
        <div
          style="
            background-color: #374151;
            padding: 5px;
            border-radius: 15px;
            max-height: 50px;
            box-sizing: border-box;
            line-height: 2;
          "
          v-for="item in machineOutputValue"
          :key="item.name"
        >
          <div>
            <span>品名：</span>
            <span>{{ item.name }}</span>
          </div>

          <div>
            <span>数量：</span>
            <span>
              <el-icon style="color: var(--cbs-machine-green)" v-if="changeName.includes(item.name)">
                <CaretTop />
              </el-icon>
              {{ item.value }}
            </span>
          </div>
        </div>
      </div>
      <div>
        <ps-chart :option="ChartOption" />
      </div>
      <div style="margin-bottom: 20px">
        <div style="background-color: #374151; padding: 20px; border-radius: 10px">
          设备数量：
          <span>{{ machineList.length }}</span>
        </div>

        <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 40px">
          <div
            v-for="item in machineStatus"
            :key="item.name"
            style="border-bottom: 1px solid #fff"
            :style="{ borderColor: item.color }"
          >
            <div>{{ item.name }}</div>
            <div style="margin-top: 10px; font-size: 18px; text-align: end">
              <span style="font-size: 22px; font-weight: bold">{{ item.total }}</span>
              <span style="font-size: 12px">台</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 分页控制区：左按钮 + 页码指示器 + 右按钮 -->
    <div class="pagination-controls" v-if="totalPages > 1">
      <button class="page-btn prev-btn" @click="prevPage" :disabled="currentPage === 0">
        <el-icon size="16" :style="{ color: currentPage === 0 ? '#fff' : '#000' }"><ArrowLeft /></el-icon>
      </button>
      <div class="page-indicator">第 {{ currentPage + 1 }} 页 / 共 {{ totalPages }} 页</div>
      <button class="page-btn next-btn" @click="nextPage" :disabled="currentPage === totalPages - 1">
        <el-icon size="16" :style="{ color: currentPage === totalPages - 1 ? '#fff' : '#000' }">
          <ArrowRight />
        </el-icon>
      </button>
    </div>
  </div>
</template>

<style scoped lang="scss">
// 视口容器 - 只显示当前页内容
.ps-machine-viewport {
  position: relative;
  overflow: hidden;
  // 高度 = 2行高度 + 间距
  height: calc(150px * 3 + 10px);
  width: 100%;
}

// 滚动容器 - 包含所有项目，通过transform实现滚动
.ps-machine {
  display: grid;
  font-size: 14px;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  grid-gap: 10px;
  grid-auto-flow: dense;
  width: 100%;
  padding: 0 10px;
}

.ps-machine-item {
  min-height: 145px;
  border-radius: 10px;
  padding: 26px 10px 0;
  border-width: 2px;
  border-style: solid;
  position: relative;
  overflow: hidden;
  color: #fff;

  // 设备ID
  .machineID {
    position: absolute;
    top: 0;
    left: 0;
    padding: 4px 8px;
    border-bottom-right-radius: 10px;
  }

  .machineName {
    font-size: 18px;
    font-weight: bold;
    text-align: center;
    vertical-align: middle;
    margin-bottom: 5px;
    transition: all 0.5s;
  }

  .sfm {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }

  .desc-item {
    line-height: 20px;

    .label {
      display: inline-block;
    }
  }
}

// 分页控制区整体样式
.pagination-controls {
  position: fixed;
  bottom: 5px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 100;
}

// 页码指示器样式
.page-indicator {
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 14px;
}

// 翻页按钮样式
.page-btn {
  width: 32px;
  height: 32px;
  border-radius: 4px;
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;

  &:hover {
    transform: scale(1.05);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
  }
}

// 左右按钮单独样式
.prev-btn,
.next-btn {
  // 可根据需要添加左右按钮的特殊样式
}

:root {
  --cbs-machine-green: #28a745; // 自定义绿色变量
}
</style>
